﻿using System;
using System.IO;
using System.ServiceModel;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Tanguy.WinForm.Utilities.DelegatesHelpers;

namespace SolutionImport
{
    class SolutionManager
    {
        IOrganizationService innerService;
        Guid importJob;
        string importPath; //Added to allow for import log download
        string zipFile; //moved to global so it can be reused int he import log download

        public SolutionManager(IOrganizationService service)
        {
            this.innerService = service;
        }

        public void ImportSolutionArchive(string archivePath, ImportSettings settings)
        {
            try
            {
                importJob = Guid.NewGuid(); //sets the global variable for the import job id
                importPath = archivePath; //sets the global variable for the import path

                ImportSolutionRequest request = new ImportSolutionRequest()
                {
                    ConvertToManaged = settings.ConvertToManaged,
                    CustomizationFile = File.ReadAllBytes(archivePath),
                    OverwriteUnmanagedCustomizations = settings.OverwriteUnmanagedCustomizations,
                    PublishWorkflows = settings.Activate,
                    ImportJobId = importJob
                };

                ImportSolutionResponse response = (ImportSolutionResponse)this.innerService.Execute(request);
            }
            catch (FaultException<OrganizationServiceFault> error)
            {
                throw new Exception("An error while importing archive: " + error.Message);
            }
            finally
            {
                if (settings.DownloadLog) { DownloadLogFile(importPath); } //Download the log file
            }
        }

        public void ImportSolutionFolder(ImportSettings settings)
        {
            try
            {
                DirectoryInfo di = new DirectoryInfo(settings.Path);
                string folderToZip = di.FullName;
                zipFile = di.Name + ".zip";

                // Zip folder content
                ZipManager.ZipFiles(settings.Path, zipFile);

                this.ImportSolutionArchive(zipFile, settings);

                File.Delete(zipFile);
            }
            catch (FaultException<OrganizationServiceFault> error)
            {
                throw new Exception("An error while importing archive: " + error.Message);
            }
            catch (Exception error)
            {
                throw new Exception("An error while importing archive: " + error.Message);
            }
            finally
            {
                if (settings.DownloadLog) { DownloadLogFile(zipFile); } //Download the log file
            }
        }

        public void PublishAll()
        {
            try
            {
                PublishAllXmlRequest request = new PublishAllXmlRequest();
                this.innerService.Execute(request);
            }
            catch (FaultException<OrganizationServiceFault> error)
            {
                throw new Exception("An error while publishing archive: " + error.Message);
            }
        }

        //Downloads the import log file
        public void DownloadLogFile(string path)
        {
            try
            {
                RetrieveFormattedImportJobResultsRequest importLogRequest = new RetrieveFormattedImportJobResultsRequest()
                {
                    ImportJobId = importJob
                };
                RetrieveFormattedImportJobResultsResponse importLogResponse = (RetrieveFormattedImportJobResultsResponse)this.innerService.Execute(importLogRequest);
                DateTime time = DateTime.Now;
                string format = "yyyy_MM_dd__HH_mm";
                File.WriteAllText(path.Replace(".zip", " ") + time.ToString(format) + ".xml", importLogResponse.FormattedResults);
            }
            catch (Exception)
            { 
                // Do nothing
            }
        }
    }
}

